package com.example.springbooteasycode.zjrc.project.Koal.CToJavaParser;

public class KoalCommandParser {
    public static void main(String[] args) {
        // 1. 定义需要解析的指令（清理后的纯 Hex 报文，实际使用时替换为真实指令）
        String hexCommand = "0000007a3033303331303139393133373430393631373030303143333135354143374238304332393633384130303235303030303030303030303030303030303030303030303030303135363030303030343030303030313536323230383035333138313134353331383743303030314333303341304230303046304630";

        // 2. 定义输入域规则（与文档对应，按顺序定义每个字段的 长度(字节)、描述 ）
        Field[] fields = {
                new Field("指令长度", 4),
                new Field("命令代码", 2),
                new Field("算法标识", 2),
                new Field("UDK 数据源", 16),
                new Field("ATC", 4),
                new Field("ARQC", 16),
                new Field("数据长度", 4),
                new Field("数据", -1), // 变长，先占位，后续根据数据长度调整
                new Field("授权响应密文的响应代码", 4)
        };

        // 3. 执行解析
        parseKoalCommand(hexCommand, fields);
    }

    /**
     * 解析 Koal 指令的核心方法
     * @param hexCommand 清理后的 Hex 指令字符串
     * @param fields     定义好的输入域规则数组
     */
    public static void parseKoalCommand(String hexCommand, Field[] fields) {
        int pos = 0; // 记录当前解析到的位置
        int dataLength = -1; // 用于存储变长字段“数据”的长度

        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            if ("数据长度".equals(field.name)) {
                // 解析数据长度字段
                String lenHex = hexCommand.substring(pos, pos + field.length * 2);
                dataLength = Integer.parseInt(lenHex, 16);
                printField(field, lenHex, dataLength);
                pos += field.length * 2;
            } else if ("数据".equals(field.name)) {
                // 处理变长数据字段
                if (dataLength == -1) {
                    System.err.println("解析异常：数据长度未正确获取，无法解析变长数据域！");
                    return;
                }
                // 数据长度是字节数，Hex 字符数 = 字节数 * 2
                int dataHexLength = dataLength * 2;
                String dataHex = hexCommand.substring(pos, pos + dataHexLength);
                printField(field, dataHex, "（变长数据，长度 " + dataLength + " 字节）");
                pos += dataHexLength;
            } else {
                // 解析固定长度字段
                String fieldHex = hexCommand.substring(pos, pos + field.length * 2);
                int decimalValue = Integer.parseInt(fieldHex, 16);
                printField(field, fieldHex, decimalValue);
                pos += field.length * 2;
            }

            // 检查是否解析完所有字符（针对固定长度场景，变长场景需特殊处理）
            if (i == fields.length - 1 && pos != hexCommand.length()) {
                System.out.println("警告：指令未完全解析，剩余字符长度：" + (hexCommand.length() - pos) + " Hex 字符");
            }
        }
    }

    /**
     * 打印字段解析结果的工具方法
     * @param field       字段元数据
     * @param hexValue    字段的 Hex 取值
     * @param extraInfo   额外信息（十进制值或变长说明）
     */
    public static void printField(Field field, String hexValue, Object extraInfo) {
        System.out.println("===== 输入域：" + field.name + " =====");
        System.out.println("Hex 取值：\t" + hexValue);
        System.out.println("长度（字节）：\t" + field.length);
        System.out.println("附加信息：\t" + extraInfo);
        System.out.println();
    }

    /**
     * 字段元数据类，用于封装 字段名、长度(字节)
     */
    static class Field {
        String name; // 字段名称
        int length;  // 长度（字节），-1 表示变长

        public Field(String name, int length) {
            this.name = name;
            this.length = length;
        }
    }
}
